package com.llsydn.demo.shopList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lilinshen
 * @title 用于加载图片并显示的类
 * @description 请填写相关描述
 * @date 2018/9/28 11:34
 */
public class ImageLoader {
    private Context context;
    private int loadingImage;
    private int errorImage;

    public ImageLoader(Context context, int loadingImage, int errorImage) {
        this.context = context;
        this.loadingImage = loadingImage;
        this.errorImage = errorImage;
    }

    //用户缓存bitmap容器对象
    private Map<String, Bitmap> cachaMap = new HashMap<String, Bitmap>();

    /**
     *  String imagePath=http://192.168.4.124:8080/android/images/f1.jpg和ImageView对象
     *  1.根据url从一级缓存中去对应的bitmap对象
     *      如果得到了，显示(结束)
     *      如果没有，进入2
     *  2.从二级缓存中查找：得到文件名并在sd卡的缓存目录下找对应的图片文件
     *      如果有：显示，缓存到一级缓存中(结束)
     *      如果没有，进入3
     *  3.显示代表提示正在加载的图片，启动分线程联网请求得到bitmap对象
     *      如果没有：显示错误的图片(结束)
     *      如果有：显示，缓存到一、二级缓存中。
     */

    /**
     * 加载图片并显示
     *
     * @param imagePath
     * @param imageView
     */
    public void loadImage(String imagePath, ImageView imageView) {
        //将需要显示的图片保存在tag值上
        imageView.setTag(imagePath);


        //1.根据url从一级缓存中去对应的bitmap对象
        Bitmap bitmap = getFromFirstCache(imagePath);
        if (null != bitmap) {
            imageView.setImageBitmap(bitmap);
            return;
        }
        //2.从二级缓存中查找：得到文件名并在sd卡的缓存目录下找对应的图片文件
        bitmap = getFromSecondCache(imagePath);
        if (null != bitmap) {
            imageView.setImageBitmap(bitmap);
            cachaMap.put(imagePath, bitmap);
            return;
        }
        //3.显示代表提示正在加载的图片，启动分线程联网请求得到bitmap对象
        loadBitmapFromThirdCache(imagePath, imageView);
    }

    /**
     * 已经缓存
     * 根据图片url从一级缓存中去对应的bitmap对象
     *
     * @param imagePath
     * @return
     */
    private Bitmap getFromFirstCache(String imagePath) {
        return cachaMap.get(imagePath);
    }

    /**
     * 二级缓存
     * 根据图片url从二级缓存中去对应的bitmap对象
     *
     * @param imagePath
     * @return
     */
    private Bitmap getFromSecondCache(String imagePath) {
        // /storage/sdcard/Android/data/packageName/files
        String files = context.getExternalFilesDir(null).getAbsolutePath();
        // http://192.168.4.124:8080/android/images/f1.jpg
        String fileName = imagePath.substring(imagePath.lastIndexOf("/") + 1);
        String filePath = files + "/" + fileName;
        return BitmapFactory.decodeFile(filePath);
    }

    /**
     * 三级缓存
     * 显示代表提示正在加载的图片，启动分线程联网请求得到bitmap对象并显示
     * AsyncTask
     *
     * @param imagePath
     * @param imageView
     */
    private void loadBitmapFromThirdCache(String imagePath, ImageView imageView) {
        new AsyncTask<Void, Void, Bitmap>() {
            //主线程，显示代表提示正在加载的图片
            @Override
            protected void onPreExecute() {
                imageView.setImageResource(loadingImage);
            }

            //分线程，联网请求得到bitmap对象
            @Override
            protected Bitmap doInBackground(Void... voids) {
                //在分线程执行，可能需要等待一定时间

                Bitmap bitmap = null;
                try {
                    //在准备请求服务器图片之前，分线程判断是否需要加载图片
                    String newImagePath = (String) imageView.getTag();
                    if (newImagePath != imagePath) { //视图已经被复用了
                        return bitmap;
                    }

                    URL url = new URL(imagePath);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setReadTimeout(5000);
                    connection.setConnectTimeout(5000);
                    connection.connect();

                    int responseCode = connection.getResponseCode();
                    if (200 == responseCode) {
                        InputStream is = connection.getInputStream();
                        bitmap = BitmapFactory.decodeStream(is);
                        is.close();
                        if (bitmap != null) {
                            //如果有：缓存到一、二级缓存中。
                            cachaMap.put(imagePath, bitmap);
                            String files = context.getExternalFilesDir(null).getAbsolutePath();
                            String fileName = imagePath.substring(imagePath.lastIndexOf("/") + 1);
                            String filePath = files + "/" + fileName;
                            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(filePath));
                        }
                    }
                    connection.disconnect();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return bitmap;
            }

            //主线程
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                //在准备显示图片之前，主线程判断是否需要显示图片
                String newImagePath = (String) imageView.getTag();
                if (newImagePath != imagePath) { //视图已经被复用了
                    return;
                }
                if (bitmap == null) {
                    //如果没有：显示一张错误的图片
                    imageView.setImageResource(errorImage);
                } else {
                    //如果有：显示
                    imageView.setImageBitmap(bitmap);
                }
            }
        }.execute();
    }
}
